<template>
  <view class="uni-badge--x">
    <slot />
    <text
      v-if="text"
      :class="classNames"
      :style="[positionStyle, customStyle, dotStyle]"
      class="uni-badge"
      @click="onClick()"
      >{{ displayValue }}</text
    >
  </view>
</template>

<script>
/**
 * Badge 数字角标
 * @description 数字角标一般和其它控件（列表、9宫格等）配合使用，用于进行数量提示，默认为实心灰色背景
 * @tutorial https://ext.dcloud.net.cn/plugin?id=21
 * @property {String} text 角标内容
 * @property {String} size = [normal|small] 角标内容
 * @property {String} type = [info|primary|success|warning|error] 颜色类型
 * 	@value info 灰色
 * 	@value primary 蓝色
 * 	@value success 绿色
 * 	@value warning 黄色
 * 	@value error 红色
 * @property {String} inverted = [true|false] 是否无需背景颜色
 * @property {Number} maxNum 展示封顶的数字值，超过 99 显示 99+
 * @property {String} absolute = [rightTop|rightBottom|leftBottom|leftTop] 开启绝对定位, 角标将定位到其包裹的标签的四角上
 * 	@value rightTop 右上
 * 	@value rightBottom 右下
 * 	@value leftTop 左上
 * 	@value leftBottom 左下
 * @property {Array[number]} offset	距定位角中心点的偏移量，只有存在 absolute 属性时有效，例如：[-10, -10] 表示向外偏移 10px，[10, 10] 表示向 absolute 指定的内偏移 10px
 * @property {String} isDot = [true|false] 是否显示为一个小点
 * @event {Function} click 点击 Badge 触发事件
 * @example <uni-badge text="1"></uni-badge>
 */

export default {
  name: 'UniBadge',
  emits: ['click'],
  props: {
    type: {
      type: String,
      default: 'error',
    },
    inverted: {
      type: Boolean,
      default: false,
    },
    isDot: {
      type: Boolean,
      default: false,
    },
    maxNum: {
      type: Number,
      default: 99,
    },
    absolute: {
      type: String,
      default: '',
    },
    offset: {
      type: Array,
      default() {
        return [0, 0]
      },
    },
    text: {
      type: [String, Number],
      default: '',
    },
    size: {
      type: String,
      default: 'small',
    },
    customStyle: {
      type: Object,
      default() {
        return {}
      },
    },
  },
  data() {
    return {}
  },
  computed: {
    width() {
      return String(this.text).length * 8 + 12
    },
    classNames() {
      const { inverted, type, size, absolute } = this
      return [
        inverted ? 'uni-badge--' + type + '-inverted' : '',
        'uni-badge--' + type,
        'uni-badge--' + size,
        absolute ? 'uni-badge--absolute' : '',
      ].join(' ')
    },
    positionStyle() {
      if (!this.absolute) return {}
      let w = this.width / 2,
        h = 10
      if (this.isDot) {
        w = 5
        h = 5
      }
      const x = `${-w + this.offset[0]}px`
      const y = `${-h + this.offset[1]}px`

      const whiteList = {
        rightTop: {
          right: x,
          top: y,
        },
        rightBottom: {
          right: x,
          bottom: y,
        },
        leftBottom: {
          left: x,
          bottom: y,
        },
        leftTop: {
          left: x,
          top: y,
        },
      }
      const match = whiteList[this.absolute]
      return match ? match : whiteList['rightTop']
    },
    dotStyle() {
      if (!this.isDot) return {}
      return {
        width: '10px',
        minWidth: '0',
        height: '10px',
        padding: '0',
        borderRadius: '10px',
      }
    },
    displayValue() {
      const { isDot, text, maxNum } = this
      return isDot ? '' : Number(text) > maxNum ? `${maxNum}+` : text
    },
  },
  methods: {
    onClick() {
      this.$emit('click')
    },
  },
}
</script>

<style lang="scss">
$uni-primary: #2979ff !default;
$uni-success: #4cd964 !default;
$uni-warning: #f0ad4e !default;
$uni-error: #dd524d !default;
$uni-info: #909399 !default;

$bage-size: 12px;
$bage-small: scale(0.8);

.uni-badge--x {
  /* #ifdef APP-NVUE */
  // align-self: flex-start;
  /* #endif */
  /* #ifndef APP-NVUE */
  display: inline-block;
  /* #endif */
  position: relative;
}

.uni-badge--absolute {
  position: absolute;
}

.uni-badge--small {
  transform: $bage-small;
  transform-origin: center center;
}

.uni-badge {
  /* #ifndef APP-NVUE */
  display: flex;
  overflow: hidden;
  box-sizing: border-box;
  font-feature-settings: 'tnum';
  min-width: 20px;
  /* #endif */
  justify-content: center;
  flex-direction: row;
  height: 20px;
  padding: 0 4px;
  line-height: 18px;
  color: #fff;
  border-radius: 100px;
  background-color: $uni-info;
  background-color: transparent;
  border: 1px solid #fff;
  text-align: center;
  font-family: 'Helvetica Neue', Helvetica, sans-serif;
  font-size: $bage-size;
  /* #ifdef H5 */
  z-index: 999;
  cursor: pointer;
  /* #endif */

  &--info {
    color: #fff;
    background-color: $uni-info;
  }

  &--primary {
    background-color: $uni-primary;
  }

  &--success {
    background-color: $uni-success;
  }

  &--warning {
    background-color: $uni-warning;
  }

  &--error {
    background-color: $uni-error;
  }

  &--inverted {
    padding: 0 5px 0 0;
    color: $uni-info;
  }

  &--info-inverted {
    color: $uni-info;
    background-color: transparent;
  }

  &--primary-inverted {
    color: $uni-primary;
    background-color: transparent;
  }

  &--success-inverted {
    color: $uni-success;
    background-color: transparent;
  }

  &--warning-inverted {
    color: $uni-warning;
    background-color: transparent;
  }

  &--error-inverted {
    color: $uni-error;
    background-color: transparent;
  }
}
</style>
